home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1997 September / Macworld (1997-09).dmg / Shareware World / Utilities / Text Processing / Alpha / Tcl / Modes / cMode.tcl < prev    next >
Text File  |  1996-08-29  |  13KB  |  452 lines

  1. # nowrap
  2.  
  3. if {$startingUp} {
  4.     addMode C dummyC { *.r } {cwarriorMenu thinkRefMenu}
  5.     addMode C++ dummyC++ {*.H *.c *.h *.cc *.cp *.cpp *.CPP *.C } { cwarriorMenu thinkRefMenu}
  6.     return
  7. }
  8.  
  9.  
  10. newModeVar C elecColon {1} 1
  11. newModeVar C elecRBrace {1} 1
  12. newModeVar C leftFillColumn {3} 0
  13. newModeVar C prefixString {//} 0 
  14. newModeVar C electricSemi {1} 1
  15. newModeVar C elecLBrace {1} 1
  16. newModeVar C elecElse {1} 1
  17. newModeVar C wordWrap {0} 1
  18. newModeVar C funcExpr {^[^ \t\(#\r/@].*\(.*\)$} 0
  19. newModeVar C parseExpr {\b([_:\w]+)\s*\(} 0
  20. newModeVar C wordBreak {[_\w]+} 0
  21. newModeVar C wordBreakPreface {[^_\w]} 0
  22. newModeVar C electricTab {1} 1
  23. newModeVar C autoMark    0    1
  24. newModeVar C stringColor    green    0
  25. newModeVar C commentColor    red    0
  26. newModeVar C funcColor        yellow    0
  27. newModeVar C keywordColor    blue    0
  28. newModeVar C CWCompSig    CWIE    0
  29. newModeVar C CWDbgSig    MWDB    0
  30. newModeVar C SymCompSig    KAHL    0
  31. newModeVar C SymDbgSig    {◊LSD}    0
  32.  
  33. set cCommentRegexp    {/\*(([^*]/)|[^*]|\r)*\*/}
  34. set cPreRegexp        {^\#[\t ]*[a-z]*}
  35. set    cKeyWords    {
  36.     void break register short enum extern int for if while struct static long continue
  37.     switch case char unsigned double float return else default goto do pascal Boolean
  38.     typedef volatile union auto sizeof size_t
  39. }
  40. if {[info exists Cwords]} {set cKeyWords [concat $cKeyWords $Cwords]}
  41. regModeKeywords -e {//} -b {/*} {*/} -c $CmodeVars(commentColor) -f $CmodeVars(funcColor) -k $CmodeVars(keywordColor) -s $CmodeVars(stringColor) -m {#} C $cKeyWords
  42.  
  43. #================================================================================
  44.  
  45. newModeVar C++ elecColon {1} 1
  46. newModeVar C++ elecRBrace {1} 1
  47. newModeVar C++ leftFillColumn {3} 0
  48. newModeVar C++ prefixString {//} 0
  49. newModeVar C++ electricSemi {1} 1
  50. newModeVar C++ wordBreak {[\w_]+} 0
  51. newModeVar C++ wordBreakPreface {[^_\w]} 0
  52. newModeVar C++ elecLBrace {1} 1
  53. newModeVar C++ elecElse {1} 1
  54. newModeVar C++ wordWrap {0} 1
  55. newModeVar C++ funcExpr {^[^ \t\(#\r/@].*\(.*\)$} 0
  56. newModeVar C++ parseExpr {\b([_:\w]+)\s*\(} 0
  57. newModeVar C++ electricTab {1} 1
  58. newModeVar C++ autoMark        0    1
  59. newModeVar C++ stringColor    green    0
  60. newModeVar C++ commentColor    red        0
  61. newModeVar C++ keywordColor    blue    0
  62. newModeVar C++ funcColor    yellow    0
  63. newModeVar C++ CWCompSig    CWIE    0
  64. newModeVar C++ CWDbgSig        MWDB    0
  65. newModeVar C++ SymCompSig    KAHL    0
  66. newModeVar C++ SymDbgSig    {◊LSD}    0
  67.  
  68.  
  69. set {c++KeyWords} {
  70.     new delete class friend protected private public template 
  71.     try catch throw operator const mutable virtual asm inline this
  72.     and and_eq bitand bitor compl not or or_eq xor xor_eq not_eq
  73.     wchar_t bool true false
  74.     static_cast dynamic_cast reinterpret_cast typeid
  75.     using namespace inherited
  76. }
  77. if {[info exists {C++words}]} {
  78.     set {c++KeyWords} [concat ${c++KeyWords} ${C++words} $cKeyWords]
  79. } else {
  80.     set {c++KeyWords} [concat ${c++KeyWords} $cKeyWords]
  81. }
  82.  
  83. regModeKeywords -e {//} -b {/*} {*/} -c [set C++modeVars(commentColor)] -f [set C++modeVars(funcColor)] -k [set C++modeVars(keywordColor)] -s [set C++modeVars(stringColor)] -m {#} {C++} ${c++KeyWords}
  84. unset cKeyWords
  85. unset {c++KeyWords}
  86.  
  87. #=============================================================================
  88. # "Electric" C functions.
  89. #=============================================================================
  90.  
  91. # returns the indent string of the line named by 'pos'
  92. proc indentString pos {
  93.     set start [lineStart $pos]
  94.     set end [nextLineStart $pos]
  95.     set text [getText $start $end]
  96.     for {set i 0} {1} {incr i} {
  97.         set c [string index $text $i]
  98.         if {($c != "\ ") && ($c != "\t")} then {
  99.             return [string range $text 0 [expr $i-1]]
  100.         }
  101.     }
  102.     return
  103. }
  104.  
  105.  
  106. # Brace on new line, same indentation. Insert on another new line, indented in.
  107. # First, see if we are on new line.
  108.  
  109. #    if {($i == $pos) || ([lookAt $pos] == " ")} {
  110. bind '\{' <s> electricLeft C
  111. bind '\{' <s> electricLeft C++
  112.  
  113.  
  114. # Brace on new line, immediate carriage return
  115.  
  116. bind '\}' <s> electricRight C
  117. bind '\}' <s> electricRight C++
  118.  
  119.  
  120. # Brace on new line, immediate carriage return. We don't do our electric stuff
  121. # if we are in the middle of a for statement.
  122. bind '\;' electricSemi C
  123. bind '\;' electricSemi C++
  124.  
  125.  
  126. proc ordSemi {} {
  127.     insertText {;}
  128. }
  129.  
  130. bind '\;' <z> ordSemi
  131.  
  132.  
  133. proc cppCR {} {
  134.     if {[lookAt [expr [getPos] - 1]] == ":"} {
  135.         if { [lookAt [getPos]] == "\r" } {
  136.             indentLine
  137.             endOfLine
  138.             carriageReturn
  139.         } else {
  140.             set pos [getPos]
  141.             endOfLine
  142.             set t [getText $pos [getPos]]
  143.             replaceText $pos [getPos] ""
  144.             indentLine
  145.             endOfLine
  146.             carriageReturn
  147.             insertText $t
  148.         }
  149.         indentLine
  150.     } else {
  151.         carriageReturn
  152.         indentLine
  153.     }
  154.     
  155. }
  156.  
  157. bind '\r'     cppCR C
  158. bind '\r'     cppCR C++
  159.         
  160. #================================================================================
  161.  
  162. # proc CMarkFile {} {
  163. #     global CmodeVars
  164. #     set pos 0
  165. #     while {![catch {search -s -f 1 -r 1 -m 0 -i 0 $CmodeVars(funcExpr) $pos} res]} {
  166. #         set start [lindex $res 0]
  167. #         set end [expr [lindex $res 1] + 1]
  168. #         set text [getText $start $end]
  169. #         if {[regexp {([a-zA-Z0-9:_]+)[ \t]*\(} $text dummy word]} {
  170. #             set tmp [expr $start + [string first $word $text]]
  171. #             set inds($word) "$tmp [expr $tmp + [string length $word]]"
  172. #         }
  173. #         set pos $end
  174. #     }
  175. #     if {[info exists inds]} {
  176. #         foreach f [lsort -ignore [array names inds]] {
  177. #             set res $inds($f)
  178. #             setNamedMark $f [lineStart [lindex $res 0]] [lindex $res 0] [lindex $res 1]
  179. #         }
  180. #     }
  181. # }
  182. #     
  183. # #The previous version would not find things like     void    *ThisFunc( xxx ) due to the asterisk
  184. # #I also truncated the pattern.  The rest is not necessary and intrusive as far as I can tell   
  185. # proc C++MarkFile {} {
  186. #     set pos 0
  187. #     while {![catch {search -s -f 1 -r 1 -m 0 -i 0 {^([^ \t\(#\r/@].*[ \t]+)?\*?([A-Za-z0-9:~_]+)[ \t\r]*\(} $pos} res]} {
  188. #         set start [lindex $res 0]
  189. #         set end [expr [lindex $res 1] + 1]
  190. #         set thistext [getText $start $end]
  191. #         #regexp doesn't like carriage returns
  192. #         regsub -all "\r" $thistext " " thistext
  193. #         #regexp doesn't like tabs either
  194. #         regsub -all "\t" $thistext " " thistext
  195. #         #if the open paren was the last character on the line the selected text included the last carriage return as well
  196. #         #trim this off now that it is changed into a space
  197. #         set thistext [string trimright $thistext]
  198. #         if {[regexp {([a-zA-Z0-9:~_]+)[ \t]*\(} $thistext dummy word]} {
  199. #             set inds($word) [lineStart [expr $start - 1]]
  200. #         }
  201. #         set pos $end
  202. #     }
  203. #     if {[info exists inds]} {
  204. #         foreach f [lsort -ignore [array names inds]] {
  205. #             set next [nextLineStart $inds($f)]
  206. #             setNamedMark $f $inds($f) $next $next
  207. #         }
  208. #     }
  209. # }
  210.  
  211.  
  212. proc CMarkFile {} {
  213.     global CmodeVars
  214.     set pos 0
  215.  
  216.     while {![catch {search -s -f 1 -r 1 -m 0 -i 0 $CmodeVars(funcExpr) $pos} res]} {
  217.         set start [lindex $res 0]
  218.         set end [expr [lindex $res 1] + 1]
  219.         set text [getText $start $end]
  220.         if {[regexp {([a-zA-Z0-9:_]+)[ \t]*\(} $text dummy word]} {
  221.             set tmp [expr $start + [string first $word $text]]
  222.             set inds($word) "$tmp [expr $tmp + [string length $word]]"
  223.         }
  224.         set pos $end
  225.     }
  226.  
  227.     ## 
  228.      # Also    mark any class or struct definitions
  229.      ##
  230.     
  231.     set markExpr {^(class|struct) \w+[ \t]*(:|\{)}
  232.     while {![catch {search -s -f 1 -r 1 -m 0 -i 0 "$markExpr" $pos} res]} {
  233.         set start [lindex $res 0]
  234.         set end [expr [lindex $res 1] -1]
  235.         set text [string trimright [getText $start $end] ]
  236.         set inds($text) "$start [expr $start + [string length $text]]"
  237.         set pos $end
  238.     }
  239.     if {[info exists inds]} {
  240.         foreach f [lsort -ignore [array names inds]] {
  241.             set res $inds($f)
  242.             setNamedMark $f [lineStart [lindex $res 0]] [lindex $res 0] [lindex $res 1]
  243.         }
  244.     }
  245. }
  246.  
  247. ## 
  248.  # -------------------------------------------------------------------------
  249.  #     
  250.  # "C++MarkFile" --
  251.  #    
  252.  #    Improved version which handles templates, operators    etc.
  253.  #    Makes use of the new mark menu in Alpha    6.2b7 which    can    handle
  254.  #    more weird characters.
  255.  #           
  256.  # -------------------------------------------------------------------------
  257.  ##
  258. proc C++MarkFile {} {
  259.     set pos 0
  260.     set markExpr {^([^ \t\(#\r/@].*[ \t]+)?\*?([A-Za-z0-9<>~_]+::[- <>A-Za-z0-9~_+=\|\*/]+|[A-Za-z0-9~_]+)[ \t\r]*\(}
  261.     while {![catch {search -s -f 1 -r 1 -m 0 -i 0 "$markExpr" $pos} res]} {
  262.         set start [lindex $res 0]
  263.         set end [expr [lindex $res 1] + 1]
  264.         set thistext [getText $start $end]
  265.         #regexp doesn't like carriage returns
  266.         regsub -all "\r" $thistext " " thistext
  267.         #regexp doesn't like tabs either
  268.         regsub -all "\t" $thistext " " thistext
  269.         #if the open paren was the last character on the line the selected text 
  270.         #included the last carriage return as well
  271.         #trim this off now that it is changed into a space
  272.         set thistext [string trimright $thistext]
  273.         if {[regexp {([A-Za-z0-9<>~_]+::[- <>A-Za-z0-9~_+=\|\*/]+|[A-Za-z0-9~_]+)[ \t]*\(} $thistext dummy word]} {
  274.             if { [string first "::" $word] != -1 } {
  275.                 regsub {(<\w+>)?::} $word " " it
  276.                 set l [lindex $it 0]
  277.                 if { $l == [lindex $it 1] } {
  278.                     set word "Construct '$l'"
  279.                 } elseif { "~$l" == [lindex $it 1] } {
  280.                     set word "Destruct '$l'"
  281.                 }
  282.             }
  283.             set inds($word) [lineStart [expr $start - 1]]
  284.         }
  285.         set pos $end
  286.     }
  287.     if {[info exists inds]} {
  288.         foreach f [lsort -ignore [array names inds]] {
  289.             set next [nextLineStart $inds($f)]
  290.             if {[string length $f] > 35} { 
  291.                 setNamedMark "[string range $f 0 31]..." "$inds($f)" $next $next
  292.             } else {
  293.                 setNamedMark $f "$inds($f)" $next $next
  294.             }
  295.         }
  296.     }
  297. }
  298.  
  299. proc setC++Mode {} {
  300.     changeMode "C++"
  301. }
  302.  
  303.  
  304.  
  305. proc dummyC {} {}
  306. proc dummyC++ {} {}
  307.  
  308.  
  309. #===============================================================================
  310.  
  311. proc CDblClick {from to} {
  312.     global tagFile
  313.     
  314.     if {[regexp {#include.*("|<)(.*)("|>)} [getText [lineStart [getPos]] [nextLineStart [getPos]]] d1 d1 inc]} {
  315.         return [cIncludeFile $inc]
  316.     }
  317.  
  318.     select $from $to
  319.     set text [getSelect]
  320.     
  321.     set lines [grep "^$text'" $tagFile]
  322.     if {[regexp {'(.*)'(.*[^\t])(\t)+∞} $lines dummy one two]} {
  323.         if {[string match "*$one*" [winNames -f]]} {
  324.             bringToFront $one
  325.         } else {
  326.             edit $one
  327.         }
  328.         set inds [search -f 1 -r 0 "$two" 0]
  329.         display [lindex $inds 0]
  330.         eval select $inds
  331.     } else {
  332.         launchForeAppl DanR
  333.         AEBuild {'DanR'} DanR {REF } "----" "“$text”"
  334.     }
  335. }
  336.  
  337. proc C++DblClick {from to shift option control} {
  338.     CDblClick $from $to
  339. }
  340.  
  341.  
  342. #===============================================================================
  343. proc cIncludeProc {menu item} {
  344.     switch $item {
  345.         open    {
  346.             set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
  347.             if {[regexp {["<]([^">]*)[">]} $text dummy fname]} {
  348.                 cIncludeFile $fname
  349.             }
  350.         }
  351.         addFolder { lappend cIncludePath [string trimright [get_directory] ":"]
  352.             rebuildHeaderMenu
  353.         }
  354.         removeFolder {
  355.             set item [listpick -p "Remove which folder?" [lsort $cIncludePath]]
  356.             set res [lsearch $cIncludePath $item]
  357.             set cIncludePath [lreplace $cIncludePath $res $res]
  358.             rebuildHeaderMenu
  359.         }
  360.     }
  361. }
  362.  
  363.  
  364. proc rebuildHeaderMenu {} {
  365.     global cIncludePath
  366.     
  367.     eval menu -n headers -p cIncludeProc $cIncludePath
  368. }
  369.  
  370.  
  371. proc cIncludeFile {fname} {
  372.     global cIncludePath
  373.     if {[file exists "[file dir [car [winNames -f]]]:$fname"]} {
  374.         edit "[file dir [car [winNames -f]]]:$fname"
  375.         return
  376.     }
  377.     
  378.     foreach path $cIncludePath {
  379.         if {[file exists "$path:$fname"]} {
  380.             edit "$path:$fname"
  381.             return
  382.         }
  383.     }
  384.     if {[askyesno "'$fname' can not be found, do you wish to add an include path?"]} {
  385.         lappend cIncludePath [string trimright [get_directory] ":"]
  386.         cIncludeFile $fname
  387.     }
  388. }
  389.  
  390.  
  391. proc getIncludeFiles {} {
  392.     global cIncludePath modeMenus mode
  393.  
  394.     if {[string match "*thinkMenu*" $modeMenus($mode)]} {return [thinkGetIncludeFiles]}
  395.  
  396.     set cid [scancontext create]
  397.     set lines {}
  398.     scanmatch $cid {#.*include.*(<|")(.*)(>|")}  {lappend lines $matchInfo(submatch1)}
  399.     set fid [open [car [winNames -f]] "r"]
  400.     scanfile $cid $fid
  401.     close $fid
  402.     scancontext delete $cid
  403.     return [lsort -ignore $lines]
  404. }
  405.  
  406.  
  407. proc editIncludeFile {fname} {
  408.     global modeMenus mode
  409.  
  410.     if {[string match "*thinkMenu*" $modeMenus($mode)]} {return [thinkEditIncludeFile $fname]}
  411.  
  412.     cIncludeFile $fname
  413. }
  414.  
  415.  
  416. #===============================================================================
  417. proc parseFuncsC {} {
  418.     global mode sortFuncsMenu
  419.     global funcExpr parseExpr
  420.     
  421.     set pos 0
  422.     if $sortFuncsMenu {
  423.         while {[set res [search -s -f 1 -r 1 -i 0 -n $funcExpr $pos]] != ""} {
  424.             if {[regexp $parseExpr [getText [car $res] [cadr $res]] dummy word]} {
  425.                 lappend m [list $word [car $res]]
  426.             }
  427.             set pos [cadr $res]
  428.         }
  429.         regsub -all "\[\{\}\]" [lsort -ignore $m] "" m
  430.     } else {
  431.         while {[set res [search -s -f 1 -r 1 -i 0 -n $funcExpr $pos]] != ""} {
  432.             if {[regexp $parseExpr [getText [car $res] [cadr $res]] dummy word]} {
  433.                 lappend m $word [car $res]
  434.             }
  435.             set pos [cadr $res]
  436.         }
  437.     }
  438.     
  439.     set files ""
  440.     foreach f [getIncludeFiles] {
  441.         lappend files $f -1
  442.     }
  443.     return [concat $files [list "(-" 0] $m]
  444. }
  445.  
  446. proc parseFuncsC++ {} {
  447.     return [parseFuncsC]
  448. }
  449.  
  450. #===============================================================================
  451.